package com.kaili.common.config.druid;

import com.alibaba.fastjson.JSON;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;

public class HandlerParameter implements HandlerMethodArgumentResolver {
    private final String BODY = "JSON_REQUEST_BODY";
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasMethodAnnotation(Rest.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        if(!request.getContentType().contains("application/json")){
            return null;
        }
        String pa = JSON.parseObject(getRequestBody(nativeWebRequest,request)).getString(methodParameter.getParameterName());
        if(methodParameter.getParameterType() == String.class){
            return pa.toString();
        }
        return JSON.parseObject(pa.toString(),methodParameter.getNestedGenericParameterType());
    }

    private String getRequestBody(NativeWebRequest webRequest, HttpServletRequest httpServletRequest){
        String st = (String)webRequest.getAttribute(BODY,NativeWebRequest.SCOPE_REQUEST);
        if(st==null){
            try {
                BufferedReader reader = httpServletRequest.getReader();
                StringBuffer sb = new StringBuffer();
                char[] buf = new char[1024];
                int rd;
                while ((rd = reader.read(buf))!=-1){
                    sb.append(buf,0,rd);
                }
                st = sb.toString();
                webRequest.setAttribute(BODY,st,NativeWebRequest.SCOPE_REQUEST);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st;
    }
}
